package hero_info

import (
	"go_server/game_server/protocol/pb"
	"go_server/game_server/util"
	"go_server/zinx/ziface"
	"go_server/zinx/zlog"
)

func (s *Hero_info_service) S2C_FuseCell(conn ziface.IConnection, roleid int64, msg *pb.FuseCellC2S) pb.ErrorCodeManager {
	hero := Hero_info_serviceObj.LoadByRoleId(roleid)
	onekey_fuselv := msg.GetFuselv()
	msgS2C := &pb.UpdateCellListS2C{}
	errCode := pb.ErrorCodeManager_HERO_INFO_ERRORRULE_FUSECELL
	cells := make(map[int32]*Cache_hero_info_field_cell)
	if onekey_fuselv > 0 {
		cvs, ec := s.onAutoOneKeyFuseCell(hero, onekey_fuselv)
		errCode = ec
		cells = cvs

	} else {
		cvs, ec := s.onFuseCell(hero, msg.Cellserids)
		errCode = ec
		cells = cvs
	}
	msgS2C.Cells = make([]*pb.HeroCellData, 0)
	for _, cv := range cells {
		msgS2C.Cells = append(msgS2C.Cells, cv.To_PbData())
	}
	defer func() {
		if msgS2C != nil {
			zlog.Debugf("ProtocolManager_FuseCell %v", msgS2C)
			defer func() {
				conn.SendBuffPBMsg(uint32(pb.ProtocolManager_FuseCell), msgS2C)
			}()
		}
	}()
	return errCode
}

func (s *Hero_info_service) onFuseCell(hero *Cache_hero_info, cellserids []int32) (map[int32]*Cache_hero_info_field_cell, pb.ErrorCodeManager) {
	if cellserids != nil && len(cellserids) > 0 {
		if hero != nil {
			if hero.RoleCells != nil {
				if len(cellserids) >= Hero_info_serviceObj.GetFuseCellCount() {
					isAllSameLvCell := true //是否是相同等级的细胞
					tmpLv := int32(0)       //当前融合的细胞等级
					for i := 0; i < len(cellserids); i++ {
						if cv, ok := hero.RoleCells[cellserids[i]]; ok {
							if tmpLv == 0 {
								tmpLv = cv.Lv
							} else {
								isAllSameLvCell = isAllSameLvCell && (cv.Lv == tmpLv)
							}
						}
					}

					maxlv := Hero_info_serviceObj.GetCellMaxLevel() //细胞最高等级
					if isAllSameLvCell && tmpLv > 0 && tmpLv < maxlv {
						if _, _, nextfusecells, fc1 := Hero_info_serviceObj.GetNextLevelFuseCells(tmpLv); fc1 {
							x2oCnt := Hero_info_serviceObj.GetFuseCellCount() //N细胞整合成一个
							usecells := make(map[int32]int32)

							for i := 0; i < x2oCnt; i++ {
								tsid := cellserids[i]
								if _, ok := usecells[tsid]; !ok {
									usecells[tsid] = 0
								}
								usecells[tsid]++
							}

							isEnough := hero.CheckEnoughCell(usecells) //是否有足够的细胞
							if tarcellcfgid, k1 := util.GetRandWeight(nextfusecells); isEnough && k1 {
								acv := make(map[int32]int32)
								acv[tarcellcfgid] = 1

								rstCells := make(map[int32]*Cache_hero_info_field_cell, 0)

								if addcells, a1 := hero.AddRoleCell(acv); a1 {
									for sid, cv := range addcells {
										rstCells[sid] = cv
									}
								}

								if removecells, a1 := hero.RemoveRoleCell(usecells); a1 {
									for sid, cv := range removecells {
										rstCells[sid] = cv
									}
								}

								defer hero.SaveDB_HeroInfo_Cells()

								return rstCells, pb.ErrorCodeManager_SUCCESS
							} else {
								return nil, pb.ErrorCodeManager_HERO_INFO_ERRORRULE_FUSECELL
							}
						} else {
							return nil, pb.ErrorCodeManager_HERO_INFO_ERRORRULE_FUSECELL
						}
					} else {
						return nil, pb.ErrorCodeManager_HERO_INFO_ERRORRULE_FUSECELL
					}
				} else {
					return nil, pb.ErrorCodeManager_HERO_INFO_ERRORRULE_FUSECELL
				}
			} else {
				return nil, pb.ErrorCodeManager_HERO_INFO_NOTEXISTS_CELL
			}
		} else {
			return nil, pb.ErrorCodeManager_HERO_INFO_NOT_ROLEID
		}
	} else {
		return nil, pb.ErrorCodeManager_HERO_INFO_NOTEXISTS_CELL
	}
}

func (s *Hero_info_service) onAutoOneKeyFuseCell(hero *Cache_hero_info, onekey_fuselv int32) (map[int32]*Cache_hero_info_field_cell, pb.ErrorCodeManager) {
	if hero != nil {
		maxlv := Hero_info_serviceObj.GetCellMaxLevel() //细胞最高等级
		if onekey_fuselv < maxlv {                      //是否达到最大融合等级
			existscells := make([]int32, 0)          //当前拥有的细胞map[int32:serid]int32:cnt
			usefusecells := make(map[int32]int32, 0) //等待融合的细胞map[int32:serid]int32:cnt

			if hero.RoleCells != nil && len(hero.RoleCells) > 0 {
				for sid, cv := range hero.RoleCells {
					if cv.Lv == onekey_fuselv && cv.Count > 0 {
						for i := 0; i < int(cv.Count); i++ {
							existscells = append(existscells, sid) //将细胞按单个展开，方便后面计算
						}
					}
				}
			}

			x2oCnt := int32(Hero_info_serviceObj.GetFuseCellCount()) //N细胞整合成一个
			newCellCnt := int32(len(existscells)) / x2oCnt           //新融合的细胞个数

			for i := 0; i < int(newCellCnt); i++ {
				for j := 0; j < int(x2oCnt); j++ {
					tsid := existscells[i*int(x2oCnt)+j]
					if _, t1 := usefusecells[tsid]; !t1 {
						usefusecells[tsid] = 0
					}
					usefusecells[tsid]++
				}
			}

			newcellcfgids := make(map[int32]int32)

			if _, _, nextfusecells, fc1 := Hero_info_serviceObj.GetNextLevelFuseCells(onekey_fuselv); fc1 {
				for i := 0; i < int(newCellCnt); i++ {
					if ncfgid, k1 := util.GetRandWeight(nextfusecells); k1 {
						if _, n1 := newcellcfgids[ncfgid]; n1 {
							newcellcfgids[ncfgid] = 0
						}
						newcellcfgids[ncfgid]++
					}
				}
			}

			rstCells := make(map[int32]*Cache_hero_info_field_cell, 0)
			//添加新细胞
			if addcells, a1 := hero.AddRoleCell(newcellcfgids); a1 {
				for sid, cv := range addcells {
					rstCells[sid] = cv
				}
			}
			//删除已使用的细胞
			if removecells, a1 := hero.RemoveRoleCell(usefusecells); a1 {
				for sid, cv := range removecells {
					rstCells[sid] = cv
				}
			}

			defer hero.SaveDB_HeroInfo_Cells()

			return rstCells, pb.ErrorCodeManager_SUCCESS
		} else {
			return nil, pb.ErrorCodeManager_HERO_INFO_ERRORRULE_FUSECELL
		}
	} else {
		return nil, pb.ErrorCodeManager_HERO_INFO_NOT_ROLEID
	}
}
